package com.star.platforms.netty;

import com.alibaba.fastjson.JSONObject;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.AttributeKey;
import org.springframework.stereotype.Component;

/**
 * 操作执行类
 * <p>
 * TextWebSocketFrame类型,表示一个文本帧
 *
 * @author sam
 * @date 2021-12-22
 */
@Component
@ChannelHandler.Sharable
public class WebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {


    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        super.handlerAdded(ctx);
        NettyConfig.getChannelGroup().add(ctx.channel());
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        System.out.println("收到消息---->  "+msg.text());

        JSONObject jsonObject = JSONObject.parseObject(msg.text());
        String uid = jsonObject.getString("uid");
        System.out.println("收到消息---->uid  "+uid);
        if (null != uid && !NettyConfig.getUserChannelMap().contains(uid)) {
            System.out.println("收到消息123---->  " + msg.text());
            NettyConfig.getUserChannelMap().put(uid, ctx.channel());
            //将用户uid存入channel中，方便随时channel中取用户id
            AttributeKey<String> key = AttributeKey.valueOf("uid");
            ctx.channel().attr(key).setIfAbsent(uid);
            //回复成功
            ctx.channel().writeAndFlush(new TextWebSocketFrame("服务器连接成功"));
        } else {
            // 前端定时请求,保持心跳连接,避免服务端误删通道
            // ctx.channel().writeAndFlush(new TextWebSocketFrame("keep alive success！"));
        }
        //前端定时请求,保持心跳连接,避免服务端误删通道
        if (null != jsonObject.getString("ping")) {
            JSONObject json = new JSONObject();
            json.put("pong", System.currentTimeMillis());
            ctx.channel().writeAndFlush(json);
        }
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        super.handlerRemoved(ctx);
        remove(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
        System.out.println("错误异常" + cause.getMessage());
        remove(ctx);
    }

    private void remove(ChannelHandlerContext ctx) {
        try {
            //删除通道
            NettyConfig.getChannelGroup().remove(ctx.channel());
            //删除用户与channel对应关系
            AttributeKey<String> key = AttributeKey.valueOf("uid");
            String uid = ctx.channel().attr(key).get();
            if (NettyConfig.getUserChannelMap() != null && uid != null) {
                NettyConfig.getUserChannelMap().remove(uid);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
